home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
UTILITY
/
TSRSRC34.ARJ
/
FMARK.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-02-14
|
16KB
|
422 lines
;==============================================================================
;FMARK.ASM - mark a position in memory,
; above which TSRs will later be cleared by RELEASE
; this version leaves a minimal size MARK in memory,
; storing the rest on disk
; requires a single command line parameter naming
; the file where the mark will be stored
;
; Syntax: FMARK [/Q] [d:][path]filename
;==============================================================================
; written for TASM
; by Kim Kokkonen, TurboPower Software
; Copyright (c) 1986,1991 Kim Kokkonen, TurboPower Software.
; May be freely distributed but not sold except by permission.
; telephone: 719-260-6641, Compuserve 76004,2611
;==============================================================================
; version 2.0 6/17/86
; start at a version number compatible with other TSR utilities
; :
; long intervening history
; :
; version 3.0 9/24/91
; add Quiet option
; version 3.1 11/4/91
; no change
; version 3.2 11/22/91
; change method of accessing high memory
; store parent len as well as parent segment
; version 3.3 1/8/92
; detect full disk while writing mark file
; erase partial mark file if any error occurs during execution
; version 3.4 2/14/92
; no change
;==============================================================================
;
Cseg segment public para
assume cs:Cseg, ds:Cseg, es:Cseg
locals @@
org 016H ;access to parent's PSP
parpsp label word
org 02CH
envseg label word ;access to environment segment
org 80H
cmdlen label byte ;command line length
org 81H
cmdlin label byte ;first character of command line
org 100H
fmark proc near
;deallocate environment block of this mark
push es
mov ax,envseg ;environment segment
mov es,ax ; into es
mov ah,49H
int 21H ;deallocate, no reason for an error to occur
pop es
;find first mcb in high memory, if any
mov ax,3000h ;get DOS version
int 21H
cmp al,3
jb @@7 ;no XMS driver possible
mov ax,4300h
int 2Fh ;multiplex call for XMS
cmp al,80h ;proper signature?
jne @@7 ;no XMS driver
mov ax,4310h ;get XMS control address
int 2Fh
mov xmsxxx,bx ;save it
mov xmsxxx[2],es
mov ah,10h
mov dx,0FFFFh
call dword ptr xmsadr ;ask to allocate FFFF paras of UMB
cmp bl,0B0h ;will fail with B0 if UMBs avail
je @@0
cmp bl,0B1h ;will fail with B1 if UMBs all allocated
jne @@7 ;no UMBs exist
@@0: int 12H
mov cl,6
shl ax,cl ;get segment of top of memory
@@1: mov es,ax
cmp byte ptr es:[0000h],'M' ;potential mcb?
jnz @@6 ;not an mcb, try next segment
@@2: mov cx,ax ;save potential start mcb in cx
@@3: inc ax
add ax,es:[0003h] ;ax = start of next mcb
jc @@5 ;can't be an mcb if we wrapped
mov es,ax ;address of next mcb
mov dl,es:[0000h]
cmp dl,'M'
jz @@3 ;good start mcb
cmp dl,'Z'
jz @@9 ;good end mcb
@@5: mov ax,cx ;restore last start segment
@@6: cmp ax,0FFFFh ;top of memory?
je @@7
inc ax ;try next segment
jmp @@1
@@7: xor cx,cx ;no matching UMB
@@9: mov firsthimcb,cx ;store first high mcb
;parse command line for file name
push cs
pop es
mov si,offset cmdlin ;point to command line
mov di,offset filnm ;point to filename storage string
cld
get1: lodsb ;get first non-blank
cmp al,32 ;skip space
je get1
cmp al,9 ;skip tab
je get1
cmp al,13 ;check for end of input
jne geto ;got a non-blank, now get the parameter
cmp di,offset filnm ;filename already specified?
jne gotit ;done if so
jmp error ;no parameter --> error
geto: cmp al,'/' ;check for option
je getoc
cmp al,'-'
jne get2
getoc: lodsb
call upcase
cmp al,'Q'
jnz operr
mov quiet,1 ;set quiet option
jmp get1 ;loop around
operr: mov dx,offset badopt ;bad option
jmp errmsg
get2: cmp di,offset filnm ;filename already specified?
jne operr ;error if so
get2a: call upcase ;upcase char in al
stosb ;store the non-blank character
lodsb ;get next character
cmp al,32
je get1 ;loop back around for blank
cmp al,9
je get1 ;loop back around for tab
cmp al,13
je gotit ;terminate for <cr>
jmp short get2a ;keep adding characters to filename
;create the specified file
gotit: mov al,0
stosb ;terminate ASCIIZ pathname
mov dx,offset filnm
xor cx,cx ;normal attribute
mov ah,3CH
int 21H ;DOS CREAT
jae store
mov dx,offset badfil ;bad file name
jmp errmsg
;store the interrupt vector table
store: mov bx,ax ;keep file handle in bx
push ds ;save ds
mov cx,400H ;1024 bytes to store
xor ax,ax
mov ds,ax ;segment 0
assume ds:nothing
mov dx,ax ;offset 0
call blockwrite ;write interrupts to file
assume ds:cseg
;store the EGA save pointer
egasav: push ds ;save ds
mov cx,0008H ;8 bytes to store
mov ax,0040H
mov ds,ax ;BIOS data segment
assume ds:nothing
mov dx,00A8H ;EGA save table pointer
call blockwrite ;write save pointers to file
assume ds:cseg
;store the interapplications communications area
intcom: push ds ;save ds
mov cx,0010H ;16 bytes to store
mov ax,0040H
mov ds,ax ;BIOS data segment
assume ds:nothing
mov dx,00F0H ;interapplications communication area
call blockwrite ;write interapp communications area to file
assume ds:cseg
;store the parent's psp
parent: push ds
mov cx,2 ;2 bytes to store
mov dx,offset parpsp ;point to parent's psp
call blockwrite ;write parent psp to file
assume ds:cseg
parlen: push ds
mov ax,ds:[parpsp]
dec ax
mov ds,ax
assume ds:nothing
mov dx,3 ;ds:dx -> parent's length
mov cx,2
call blockwrite ;write parent psp to file
assume ds:cseg
;determine whether EMS is present
ems: push bx ;temporarily store the file handle
xor bx,bx ;zero the EMS handle count in case EMS not present
mov dx,offset emsnm
mov ax,3D00H
int 21H
jb sthand ;EMS driver not installed
;EMS present, close the open "handle" first
mov bx,ax ;EMS handle into bx
mov ah,3EH
int 21H ;close handle
;get the current EMS page map
mov ah,4DH
mov di,offset emsmap ;es=cs already
xor bx,bx ;required by some versions of EMM (bug workaround)
cld ;required by some versions of EMM
int 67H
or ah,ah
jz sthand ;result ok
xor bx,bx ;error, return zero EMS handles
;store the number of active handles
sthand: mov emscnt,bx ;count of active handles
;write the handle table to disk
shl bx,1
shl bx,1 ;4 bytes per handle
inc bx
inc bx ;2 more bytes for the handle count
mov cx,bx ;number of bytes to write
pop bx ;get file handle back
mov dx,offset emscnt ;what we're writing
push ds
call blockwrite ;write EMS table to file
assume ds:cseg
;write the allocated mcb chain
stomcb: push bx ;save file handle
mov ah,52H ;get first mcb segment
int 21H
mov ax,es:[bx-2] ;ax=first mcb
push cs
pop es ;es=cs
mov di,emscnt ;get starting address of mcbmap
shl di,1
shl di,1
add di,offset emsmap
mov si,di ;cs:[si] -> mcbcnt
add di,2 ;cs:[di] -> mcbmap
xor cx,cx ;cx will count mcbs
cld
push ds
assume ds:nothing
mcbnext:stosw ;store mcb segment held by ax
mov ds,ax ;ds:[0] points to mcb
mov ax,ds:[1] ;get mcb owner
stosw ;store it
inc cx ;increment count
cmp byte ptr ds:[0],'Z' ;end of mcb chain?
je mcbdone
mov ax,ds ;restore ax to mcb segment
inc ax ;skip over mcb itself
add ax,ds:[3] ;add length of memory block
jmp mcbnext
mcbdone:mov ax,cs:firsthimcb ;check for high memory
or ax,ax
jz mcbend
mov cs:firsthimcb,0 ;only do it once
jmp mcbnext
mcbend: pop ds
assume ds:cseg
mov [si],cx ;store number of mcbs
sub di,si ;di=number of bytes in mcb group table
mov cx,di ;count of bytes in cx
mov dx,si ;what we're writing (mcbcnt+mcbmap)
pop bx ;get file handle back
push ds
call blockwrite ;write mcb table to file
assume ds:cseg
;close up the table file
closfl: mov ah,3EH
int 21H ;close handle
jae idstr ;ok, continue
mov dx,offset badcls ;error while closing file
jmp delfil
;put a standard ID string into the PSP for RELEASE to check
idstr: mov si,offset id
mov di,60H ;unused area of the PSP
mov cx,idlen ;characters in ID string
cld
rep movsb ;copy string
;copy the filename into the command tail
mov si,offset filnm
mov di,offset cmdlin
xor cx,cx
nxtf: lodsb
or al,al
jz donf
inc cx
stosb
jmp nxtf
donf: mov cmdlen,cl
;print message and TSR
gores: cmp quiet,0 ;check quiet flag
jnz gores1
mov dx,offset didit
mov ah,9
int 21H ;write success message including filename
mov dx,offset crlf ;newline
mov ah,9
int 21H
gores1: xor dx,dx ;get number of paragraphs to keep
mov dl,cmdlen ;length of command line
add dx,0090H ;rest of PSP plus paragraph margin
mov cl,4
shr dx,cl ;convert to paragraphs
mov ax,3100H
int 21H ;terminate but stay resident
;close mark file, delete it, show error message
errclo: mov ah,3EH
int 21H ;close handle, ignore error
;delete mark file and show error message
assume ds:cseg
delfil: push dx
mov dx,offset filnm
mov ah,41H
int 21H
pop dx
;error output - show syntax line
;dx has offset of error message
errmsg: mov ah,9
int 21H
error:
mov dx,offset syntax
mov ah,9
int 21H
mov ax,4C01H
int 21H
fmark endp
;blockwrite assumes that ds was pushed before the call
blockwrite proc near
mov ah,40H
int 21H ;write block to file
pop dx ;get return address
pop ds ;get ds back
assume ds:cseg
push dx ;return address back on stack
mov dx,offset nowrit
jc errclo ;jump if error during write
cmp ax,cx
jne errclo ;jump if not all bytes written
ret
blockwrite endp
upcase proc near
cmp al,'a'
jb noup
cmp al,'z'
ja noup
and al,0DFH ;uppercase
noup: ret
upcase endp
emsnm db 'EMMXXXX0',0 ;file name for testing EMS presence
id db 'FM3.4 TSR' ;id string for RELEASE check
idlen equ $-id
;messages
badfil db 13,10,'Could not open file for writing',36
nowrit db 13,10,'Error while writing',36
badcls db 13,10,'Error closing table file',36
badopt db 13,10,'Bad command line option',36
syntax db 13,10,'Syntax: FMARK [/Q] [d:][path]filename'
crlf db 13,10,36
didit db 'FMARK 3.4, Copyright 1991 TurboPower Software',13,10
didit2 db 'Marked current memory position in '
;data storage area
filnm db 50H dup (36) ;mark file name
quiet db 0 ;quiet flag
xmsadr label dword ;XMS control address
xmsxxx dw 2 dup (0)
firsthimcb dw 0 ;segment of first mcb in high mem
emscnt dw 0 ;holds number of active pages in map that follows
emsmap = $ ;EMS page map (up to 1024 bytes)
mcbcnt = emsmap+400H ;number of allocated mcbs
mcbmap = mcbcnt+2 ;MCB map (up to 1024 bytes)
Cseg ends
end Fmark